# all assignemts need to work gracefully even on a non-Debian host
DEBIAN_VERSION = $(shell sed -n '1s/^[^(]*(\([^)]\+\)).*/\1/p' debian/changelog 2>/dev/null || echo "0.0-1")
DEBIAN_UPSTREAM_VERSION = $(shell echo "$(DEBIAN_VERSION)" | cut -f 1 -d -)
DEBIAN_SOURCE_PACKAGE_NAME := $(shell sed -n '1s/^\([^ ]\+\).*/\1/p' debian/changelog 2>/dev/null || echo "unnamed")
DEBIAN_CHANGES_FILE = $(DIR_DEBIAN_BUILD)/$(DEBIAN_SOURCE_PACKAGE_NAME)_$(DEBIAN_VERSION)_$(DEBIAN_BUILD_ARCH).changes
# we can tolerate that "debhelper" is not installed at this moment (no need for warnings)
DEBIAN_BINARY_PACKAGE_NAMES := $(shell dh_listpackages 2>/dev/null || true)
DEBIAN_SIMPLIFIED_PACKAGE_FILES := $(patsubst %,$(DIR_DEBIAN_SIMPLIFIED_PACKAGE_FILES)/%.deb,$(DEBIAN_BINARY_PACKAGE_NAMES))
DEBIAN_BUILD_STAMP = $(DIR_BUILD)/.debian-build-$(BUILD_ID)-$(DEBIAN_BUILD_ARCH).stamp
DEBIAN_SOURCE_ARCHIVE_STAMP = $(DIR_BUILD)/.debian-source-archive-$(BUILD_ID).stamp
DEBIAN_SOURCE_ARCHIVE = $(abspath $(DIR_DIST)/$(DEBIAN_SOURCE_PACKAGE_NAME)_$(DEBIAN_UPSTREAM_VERSION).orig.tar.gz)
# determine the suitable Makefile target for the given Debian package source format
DEBIAN_BUILD_MAKEFILE_TARGET = $(shell grep -qF "(git)" debian/source/format && echo "dist-deb-simple-git-package" || echo "dist-deb-git-submodules-package")
# command and arguments used when calling dpkg-buildpackage
# e.g. "dpkg-buildpackage --no-sign"
DEBIAN_BUILDPACKAGE_COMMAND ?= dpkg-buildpackage
# command and arguments used when uploading the package(s) to a deb repository
# e.g. "dput --unchecked"
DEB_UPLOAD_COMMAND ?= dput
# override this variable for potential git submodule directories
DEBIAN_PACKAGE_SUBMODULE_DIRECTORIES ?=


.PHONY: help
help: help-deb

.PHONY: help-deb
help-deb:
	@echo "Debian-specific packaging targets:"
	@echo "    dist-deb"
	@echo "    clean-deb"
	@echo "    upload-deb"
	@echo

.PHONY: dist
dist: dist-deb

.PHONY: dist-deb
dist-deb: $(DEBIAN_CHANGES_FILE) $(DEBIAN_BUILD_STAMP)

$(DEBIAN_CHANGES_FILE): Makefile debian/control debian/rules $(DEBIAN_BUILD_STAMP)

$(DEBIAN_BUILD_STAMP):
	$(MAKE) "$(DEBIAN_BUILD_MAKEFILE_TARGET)"
	mkdir -p "$$(dirname "$(DEBIAN_BUILD_STAMP)")"
	touch "$(DEBIAN_BUILD_STAMP)"

.PHONY: prep-source
# double-colon rules allow for multiple independent targets with
# the same name. another makefile may define another target
# with the same name to do pre-source-archive work
prep-source::
	true

# Building a debian source archive is required for repositories containing submodules required for
# the build process.
$(DEBIAN_SOURCE_ARCHIVE_STAMP):
	$(MAKE) prep-source
	mkdir -p "$$(dirname "$(DEBIAN_SOURCE_ARCHIVE)")"
	rm -f "$(DEBIAN_SOURCE_ARCHIVE)" "$(basename $(DEBIAN_SOURCE_ARCHIVE))"
	git archive --prefix=$(DEBIAN_SOURCE_PACKAGE_NAME)-$(DEBIAN_UPSTREAM_VERSION)/ \
		-o "$(basename $(DEBIAN_SOURCE_ARCHIVE))" HEAD
	# We also need the code from potential submodules.
	# The flags directive ensures that the transform is only applied to regular files and
	# hardlinks but not symlinks.
	# see https://www.gnu.org/software/tar/manual/html_section/tar_52.html#transform
	if [ -n "$(DEBIAN_PACKAGE_SUBMODULE_DIRECTORIES)" ]; then \
		tar --append --transform='flags=rSh;s#^#$(DEBIAN_SOURCE_PACKAGE_NAME)-$(DEBIAN_UPSTREAM_VERSION)/#' \
			-f "$(basename $(DEBIAN_SOURCE_ARCHIVE))" \
			$(DEBIAN_PACKAGE_SUBMODULE_DIRECTORIES); fi
	gzip -f "$(basename $(DEBIAN_SOURCE_ARCHIVE))"
	mkdir -p "$$(dirname "$(DEBIAN_SOURCE_ARCHIVE_STAMP)")"
	touch "$(DEBIAN_SOURCE_ARCHIVE_STAMP)"

.PHONY: dist-deb-git-submodules-package
dist-deb-git-submodules-package: $(DEBIAN_SOURCE_ARCHIVE_STAMP)
	$(RM) -r "$(DIR_DEBIAN_BUILD)"
	mkdir -p "$(DIR_DEBIAN_BUILD)"
	ln -s "$(DEBIAN_SOURCE_ARCHIVE)" "$(DIR_DEBIAN_BUILD)"
	tar xzf "$(DEBIAN_SOURCE_ARCHIVE)" -C "$(DIR_DEBIAN_BUILD)"
	cd "$(DIR_DEBIAN_BUILD)/$(DEBIAN_SOURCE_PACKAGE_NAME)-$(DEBIAN_UPSTREAM_VERSION)" \
		&& $(DEBIAN_BUILDPACKAGE_COMMAND)
	@# Remove the out-of-tree build directory.
	@# It serves no purpose and should not end up in artifacts.
	$(RM) -r "$(DIR_DEBIAN_BUILD)/$(DEBIAN_SOURCE_PACKAGE_NAME)-$(DEBIAN_UPSTREAM_VERSION)"

.PHONY: dist-deb-simple-git-package
dist-deb-simple-git-package:
	$(DEBIAN_BUILDPACKAGE_COMMAND)
	mkdir -p "$(DIR_DEBIAN_BUILD)"
	sed -n '/^Files:$$/,/^$$/p' "../$(notdir $(DEBIAN_CHANGES_FILE))" \
			| grep "^ " | awk '{print $$5}' | while read fname; do \
		mv "../$$fname" "$(DIR_DEBIAN_BUILD)/"; \
	done
	mv "../$(notdir $(DEBIAN_CHANGES_FILE))" "$(DEBIAN_CHANGES_FILE)"

# copy deb packages created via dpkg-buildpackage to the simplified debian export directory
$(DEBIAN_SIMPLIFIED_PACKAGE_FILES): $(DIR_DEBIAN_SIMPLIFIED_PACKAGE_FILES)/%.deb: $(DEBIAN_BUILD_STAMP)
	@mkdir -p "$(DIR_DEBIAN_SIMPLIFIED_PACKAGE_FILES)"
	cp $(DIR_DEBIAN_BUILD)/$*_$(DEBIAN_VERSION)_*.deb "$@"

.PHONY: dist-deb-packages-directory
dist-deb-packages-directory: $(DEBIAN_SIMPLIFIED_PACKAGE_FILES)

.PHONY: upload
upload: upload-deb

.PHONY: upload-deb
upload-deb: $(DEBIAN_CHANGES_FILE) check-dput-config
	$(DEB_UPLOAD_COMMAND) "$(DEBIAN_UPLOAD_TARGET)" "$(DEBIAN_CHANGES_FILE)"

.PHONY: clean
clean: clean-deb

.PHONY: clean-deb
clean-deb:
	@# remove only debhelper-related build files (without calling "make clean")
	dh_clean || true
